# -*- coding: utf-8 -*-

import json
import csv
import io
from datetime import datetime, timedelta
from odoo import http
from odoo.http import request
from .api_base import APIBaseController


class LogController(APIBaseController):
    """日志管理控制器"""
    
    def __init__(self):
        super().__init__()
        self.model_name = 'device.operation.log'
    
    def get_json_data(self):
        """获取JSON请求数据"""
        try:
            return json.loads(request.httprequest.data.decode('utf-8'))
        except:
            return {}
    
    def log_operation(self, user_id, module, operation_type, content, **kwargs):
        """记录操作日志"""
        try:
            OperationLog = request.env['device.operation.log'].sudo()
            OperationLog.create_log(
                operator_id=user_id,
                module=module,
                operation_type=operation_type,
                content=content,
                **kwargs
            )
        except Exception as e:
            # 日志记录失败不影响主流程
            pass
    
    @http.route('/api/device/log/list', type='http', auth='none', methods=['GET'], csrf=False, cors='*')
    def get_log_list(self, **kwargs):
        """获取操作日志列表"""
        try:
            # 验证token
            current_user = self.verify_token()
            if not current_user:
                return self.error_response('未授权访问', 401)
            
            user_id = current_user.id
            
            # 检查日志查看权限
            if not self.check_permission('log:view'):
                return self.error_response('无权限查看日志', 403)
            
            # 获取查询参数
            page = int(kwargs.get('page', 1))
            limit = int(kwargs.get('limit', 20))
            
            # 构建过滤条件
            filters = {}
            
            # 操作人过滤
            if kwargs.get('operator_name'):
                filters['operator_name'] = kwargs.get('operator_name')
            
            if kwargs.get('operator_id'):
                filters['operator_id'] = int(kwargs.get('operator_id'))
            
            # 操作模块过滤
            if kwargs.get('operation_module'):
                filters['operation_module'] = kwargs.get('operation_module')
            
            # 操作类型过滤
            if kwargs.get('operation_type'):
                filters['operation_type'] = kwargs.get('operation_type')
            
            # 操作状态过滤
            if kwargs.get('operation_status'):
                filters['operation_status'] = kwargs.get('operation_status')
            
            # 时间范围过滤
            if kwargs.get('start_time'):
                try:
                    filters['start_time'] = datetime.strptime(kwargs.get('start_time'), '%Y-%m-%d %H:%M:%S')
                except ValueError:
                    filters['start_time'] = datetime.strptime(kwargs.get('start_time'), '%Y-%m-%d')
            
            if kwargs.get('end_time'):
                try:
                    filters['end_time'] = datetime.strptime(kwargs.get('end_time'), '%Y-%m-%d %H:%M:%S')
                except ValueError:
                    filters['end_time'] = datetime.strptime(kwargs.get('end_time'), '%Y-%m-%d')
            
            # IP地址过滤
            if kwargs.get('ip_address'):
                filters['ip_address'] = kwargs.get('ip_address')
            
            # 部门过滤
            if kwargs.get('department_id'):
                filters['department_id'] = int(kwargs.get('department_id'))
            
            # 内容关键字过滤
            if kwargs.get('keyword'):
                filters['content_keyword'] = kwargs.get('keyword')
            
            # 数据权限控制
            User = request.env['device.user'].sudo()
            current_user = User.browse(user_id)
            data_scope = current_user.get_user_data_scope()
            
            if data_scope != 'all' and not current_user.is_admin:
                if data_scope == 'dept':
                    filters['department_id'] = current_user.department_id.id
                elif data_scope == 'dept_and_child':
                    dept_ids = current_user.get_data_scope_department_ids()
                    if dept_ids:
                        # 这里需要修改搜索逻辑以支持多个部门
                        pass
                elif data_scope == 'self':
                    filters['operator_id'] = user_id
            
            # 搜索日志
            Log = request.env['device.operation.log'].sudo()
            logs = Log.search_logs(filters)
            
            # 分页
            total = len(logs)
            start_index = (page - 1) * limit
            end_index = start_index + limit
            paged_logs = logs[start_index:end_index]
            
            # 格式化数据
            data = []
            for log in paged_logs:
                data.append({
                    'id': log.id,
                    'operator_name': log.operator_name,
                    'operator_username': log.operator_username,
                    'operation_module': log.operation_module,
                    'operation_type': log.operation_type,
                    'operation_content': log.operation_content,
                    'operation_time': log.operation_time.strftime('%Y-%m-%d %H:%M:%S') if log.operation_time else '',
                    'ip_address': log.ip_address or '',
                    'operation_status': log.operation_status,
                    'target_model': log.target_model or '',
                    'target_name': log.target_name or '',
                    'execution_time': log.execution_time or 0,
                    'department_name': log.department_id.name if log.department_id else '',
                    'error_message': log.error_message or ''
                })
            
            return self.success_response('获取成功', {
                'list': data,
                'total': total,
                'page': page,
                'limit': limit,
                'pages': (total + limit - 1) // limit
            })
            
        except Exception as e:
            return self.error_response(f'获取日志列表失败: {str(e)}')
    
    @http.route('/api/device/log/detail/<int:log_id>', type='http', auth='none', methods=['GET'], csrf=False, cors='*')
    def get_log_detail(self, log_id, **kwargs):
        """获取日志详情"""
        try:
            # 验证token
            current_user = self.verify_token()
            if not current_user:
                return self.error_response('未授权访问', 401)
            
            user_id = current_user.id
            
            # 检查日志查看权限
            if not self.check_permission('log:view'):
                return self.error_response('无权限查看日志', 403)
            
            # 获取日志详情
            Log = request.env['device.operation.log'].sudo()
            log = Log.browse(log_id)
            
            if not log.exists():
                return self.error_response('日志不存在', 404)
            
            # 数据权限检查
            User = request.env['device.user'].sudo()
            current_user = User.browse(user_id)
            
            if not current_user.is_admin:
                data_scope = current_user.get_user_data_scope()
                if data_scope == 'self' and log.operator_id.id != user_id:
                    return self.error_response('无权限查看该日志', 403)
                elif data_scope == 'dept' and log.department_id.id != current_user.department_id.id:
                    return self.error_response('无权限查看该日志', 403)
            
            # 格式化数据
            data = {
                'id': log.id,
                'operator_name': log.operator_name,
                'operator_username': log.operator_username,
                'operation_module': log.operation_module,
                'operation_type': log.operation_type,
                'operation_content': log.operation_content,
                'operation_detail': log.operation_detail or '',
                'operation_time': log.operation_time.strftime('%Y-%m-%d %H:%M:%S') if log.operation_time else '',
                'ip_address': log.ip_address or '',
                'user_agent': log.user_agent or '',
                'request_method': log.request_method or '',
                'request_url': log.request_url or '',
                'operation_status': log.operation_status,
                'target_model': log.target_model or '',
                'target_id': log.target_id or 0,
                'target_name': log.target_name or '',
                'execution_time': log.execution_time or 0,
                'department_name': log.department_id.name if log.department_id else '',
                'error_message': log.error_message or ''
            }
            
            return self.success_response('获取成功', data)
            
        except Exception as e:
            return self.error_response(f'获取日志详情失败: {str(e)}')
    
    @http.route('/api/device/log/statistics', type='http', auth='none', methods=['GET'], csrf=False, cors='*')
    def get_log_statistics(self, **kwargs):
        """获取日志统计信息"""
        try:
            # 验证token
            current_user = self.verify_token()
            if not current_user:
                return self.error_response('未授权访问', 401)
            
            user_id = current_user.id
            
            # 检查日志查看权限
            if not self.check_permission('log:view'):
                return self.error_response('无权限查看日志统计', 403)
            
            # 构建过滤条件
            filters = {}
            
            # 时间范围过滤（默认最近30天）
            if kwargs.get('start_time'):
                try:
                    filters['start_time'] = datetime.strptime(kwargs.get('start_time'), '%Y-%m-%d')
                except ValueError:
                    filters['start_time'] = datetime.now() - timedelta(days=30)
            else:
                filters['start_time'] = datetime.now() - timedelta(days=30)
            
            if kwargs.get('end_time'):
                try:
                    filters['end_time'] = datetime.strptime(kwargs.get('end_time'), '%Y-%m-%d')
                except ValueError:
                    filters['end_time'] = datetime.now()
            else:
                filters['end_time'] = datetime.now()
            
            # 数据权限控制
            User = request.env['device.user'].sudo()
            current_user = User.browse(user_id)
            
            if not current_user.is_admin:
                data_scope = current_user.get_user_data_scope()
                if data_scope == 'dept':
                    filters['department_id'] = current_user.department_id.id
                elif data_scope == 'self':
                    filters['operator_id'] = user_id
            
            # 获取统计信息
            Log = request.env['device.operation.log'].sudo()
            stats = Log.get_statistics(filters)
            
            return self.success_response('获取成功', stats)
            
        except Exception as e:
            return self.error_response(f'获取日志统计失败: {str(e)}')
    
    @http.route('/api/device/log/export', type='http', auth='none', methods=['GET'], csrf=False, cors='*')
    def export_logs(self, **kwargs):
        """导出日志"""
        try:
            # 验证token
            current_user = self.verify_token()
            if not current_user:
                return self.error_response('未授权访问', 401)
            
            user_id = current_user.id
            
            # 检查日志导出权限
            if not self.check_permission('log:export'):
                return self.error_response('无权限导出日志', 403)
            
            # 构建过滤条件（与列表查询相同的逻辑）
            filters = {}
            
            if kwargs.get('operator_name'):
                filters['operator_name'] = kwargs.get('operator_name')
            
            if kwargs.get('operation_module'):
                filters['operation_module'] = kwargs.get('operation_module')
            
            if kwargs.get('operation_type'):
                filters['operation_type'] = kwargs.get('operation_type')
            
            if kwargs.get('start_time'):
                try:
                    filters['start_time'] = datetime.strptime(kwargs.get('start_time'), '%Y-%m-%d')
                except ValueError:
                    pass
            
            if kwargs.get('end_time'):
                try:
                    filters['end_time'] = datetime.strptime(kwargs.get('end_time'), '%Y-%m-%d')
                except ValueError:
                    pass
            
            # 数据权限控制
            User = request.env['device.user'].sudo()
            current_user = User.browse(user_id)
            
            if not current_user.is_admin:
                data_scope = current_user.get_user_data_scope()
                if data_scope == 'dept':
                    filters['department_id'] = current_user.department_id.id
                elif data_scope == 'self':
                    filters['operator_id'] = user_id
            
            # 搜索日志
            Log = request.env['device.operation.log'].sudo()
            logs = Log.search_logs(filters)
            
            # 限制导出数量
            max_export = 10000
            if len(logs) > max_export:
                logs = logs[:max_export]
            
            # 创建CSV文件
            output = io.StringIO()
            writer = csv.writer(output)
            
            # 写入表头
            headers = [
                '操作人', '用户名', '操作模块', '操作类型', '操作内容',
                '操作时间', 'IP地址', '操作状态', '目标对象', '执行时长(ms)', '部门', '错误信息'
            ]
            writer.writerow(headers)
            
            # 写入数据
            for log in logs:
                row = [
                    log.operator_name or '',
                    log.operator_username or '',
                    log.operation_module or '',
                    log.operation_type or '',
                    log.operation_content or '',
                    log.operation_time.strftime('%Y-%m-%d %H:%M:%S') if log.operation_time else '',
                    log.ip_address or '',
                    log.operation_status or '',
                    log.target_name or '',
                    log.execution_time or 0,
                    log.department_id.name if log.department_id else '',
                    log.error_message or ''
                ]
                writer.writerow(row)
            
            # 生成文件名
            filename = f"operation_logs_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
            
            # 记录导出操作日志
            self.log_operation(
                user_id, 'system', 'export',
                f'导出操作日志，共{len(logs)}条记录'
            )
            
            # 返回CSV文件
            csv_content = output.getvalue()
            output.close()
            
            response = request.make_response(
                csv_content,
                headers=[
                    ('Content-Type', 'text/csv; charset=utf-8'),
                    ('Content-Disposition', f'attachment; filename="{filename}"')
                ]
            )
            
            return response
            
        except Exception as e:
            return self.error_response(f'导出日志失败: {str(e)}')
    
    @http.route('/api/device/log/cleanup', type='http', auth='none', methods=['POST'], csrf=False, cors='*')
    def cleanup_logs(self, **kwargs):
        """清理旧日志"""
        try:
            # 验证token
            current_user = self.verify_token()
            if not current_user:
                return self.error_response('未授权访问', 401)
            
            user_id = current_user.id
            
            # 检查日志管理权限
            if not self.check_permission('log:manage'):
                return self.error_response('无权限管理日志', 403)
            
            # 获取请求数据
            data = self.get_json_data()
            days = int(data.get('days', 90))  # 默认保留90天
            
            if days < 30:
                return self.error_response('保留天数不能少于30天')
            
            # 清理日志
            Log = request.env['device.operation.log'].sudo()
            deleted_count = Log.cleanup_old_logs(days)
            
            # 记录清理操作日志
            self.log_operation(
                user_id, 'system', 'delete',
                f'清理{days}天前的操作日志，共清理{deleted_count}条记录'
            )
            
            return self.success_response('清理成功', {'deleted_count': deleted_count})
            
        except Exception as e:
            return self.error_response(f'清理日志失败: {str(e)}')
    
    @http.route('/api/device/log/modules', type='http', auth='none', methods=['GET'], csrf=False, cors='*')
    def get_log_modules(self, **kwargs):
        """获取日志模块列表"""
        try:
            # 验证token
            user_info = self.verify_token()
            if not user_info:
                return self.error_response('未授权访问', 401)
            
            # 获取模块选项
            Log = request.env['device.operation.log'].sudo()
            modules = Log._fields['operation_module'].selection
            
            module_list = [{'value': k, 'label': v} for k, v in modules]
            
            return self.success_response('获取成功', module_list)
            
        except Exception as e:
            return self.error_response(f'获取模块列表失败: {str(e)}')
    
    @http.route('/api/device/log/types', type='http', auth='none', methods=['GET'], csrf=False, cors='*')
    def get_log_types(self, **kwargs):
        """获取日志操作类型列表"""
        try:
            # 验证token
            user_info = self.verify_token()
            if not user_info:
                return self.error_response('未授权访问', 401)
            
            # 获取操作类型选项
            Log = request.env['device.operation.log'].sudo()
            types = Log._fields['operation_type'].selection
            
            type_list = [{'value': k, 'label': v} for k, v in types]
            
            return self.success_response('获取成功', type_list)
            
        except Exception as e:
            return self.error_response(f'获取操作类型列表失败: {str(e)}')
